/*
 * Copyright 2001-2025 Artima, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.scalatest.freespec

import org.scalatest._
import org.scalatest.exceptions._
import org.scalactic.{source, Prettifier}
import scala.concurrent.Future
import org.scalatest.Suite.autoTagClassAnnotations
import verbs.BehaveWord
import org.scalatest.fixture.{AsyncPendingTransformer, NoArgTestWrapper}
import scala.util.Try

/**
 * Implementation trait for class <code>FixtureAsyncFreeSpec</code>, which is
 * a sister class to <code>org.scalatest.freespec.AsyncFreeSpec</code> that can pass a
 * fixture object into its tests.
 *
 * <p>
 * <a href="FixtureAsyncFreeSpec.html"><code>FixtureAsyncFreeSpec</code></a> is a class,
 * not a trait, to minimize compile time given there is a slight compiler
 * overhead to mixing in traits compared to extending classes. If you need
 * to mix the behavior of <code>FixtureAsyncFreeSpec</code> into some other
 * class, you can use this trait instead, because class
 * <code>FixtureAsyncFreeSpec</code> does nothing more than extend this trait and add a nice <code>toString</code> implementation.
 * </p>
 *
 * <p>
 * See the documentation of the class for a <a href="FixtureAsyncFreeSpec.html">detailed
 * overview of <code>FixtureAsyncFreeSpec</code></a>.
 * </p>
 *
 * @author Bill Venners
 */
//SCALATESTJS-ONLY @scala.scalajs.reflect.annotation.EnableReflectiveInstantiation
//SCALATESTNATIVE-ONLY @scala.scalanative.reflect.annotation.EnableReflectiveInstantiation
@Finders(Array("org.scalatest.finders.FreeSpecFinder"))
trait FixtureAsyncFreeSpecLike extends org.scalatest.FixtureAsyncTestSuite with Informing with Notifying with Alerting with Documenting { thisSuite =>

  private final val engine = new AsyncFixtureEngine[FixtureParam](Resources.concurrentFixtureFreeSpecMod, "FixtureFreeSpec")

  import engine._

  /**
   * Returns an <code>Informer</code> that during test execution will forward strings passed to its
   * <code>apply</code> method to the current reporter. If invoked in a constructor, it
   * will register the passed string for forwarding later during test execution. If invoked from inside a scope,
   * it will forward the information to the current reporter immediately.  If invoked from inside a test function,
   * it will record the information and forward it to the current reporter only after the test completed, as <code>recordedEvents</code>
   * of the test completed event, such as <code>TestSucceeded</code>. If invoked at any other time, it will print to the standard output.
   * This method can be called safely by any thread.
   */
  protected def info: Informer = atomicInformer.get

  /**
   * Returns an <code>Notifier</code> that during test execution will forward strings (and other objects) passed to its
   * <code>apply</code> method to the current reporter. If invoked in a constructor, it
   * will register the passed string for forwarding later during test execution. If invoked while this
   * <code>FixtureAsyncFreeSpec</code> is being executed, such as from inside a test function, it will forward the information to
   * the current reporter immediately. If invoked at any other time, it will
   * print to the standard output. This method can be called safely by any thread.
   */
  protected def note: Notifier = atomicNotifier.get

  /**
   * Returns a <code>Alerter</code> that during test execution will forward strings (and other objects) passed to its
   * <code>apply</code> method to the current reporter. If invoked in a constructor, it
   * will register the passed string for forwarding later during test execution. If invoked while this
   * <code>FixtureAsyncFreeSpec</code> is being executed, such as from inside a test function, it will forward the information to
   * the current reporter immediately. If invoked at any other time, it will
   * print to the standard output. This method can be called safely by any thread.
   */
  protected def alert: Alerter = atomicAlerter.get

  /**
   * Returns a <code>Documenter</code> that during test execution will forward strings passed to its
   * <code>apply</code> method to the current reporter. If invoked in a constructor, it
   * will register the passed string for forwarding later during test execution. If invoked from inside a scope,
   * it will forward the information to the current reporter immediately.  If invoked from inside a test function,
   * it will record the information and forward it to the current reporter only after the test completed, as <code>recordedEvents</code>
   * of the test completed event, such as <code>TestSucceeded</code>. If invoked at any other time, it will print to the standard output.
   * This method can be called safely by any thread.
   */
  protected def markup: Documenter = atomicDocumenter.get

  private final def registerAsyncTestImpl(testText: String, testTags: Tag*)(testFun: FixtureParam => Future[compatible.Assertion], pos: source.Position): Unit = {
    engine.registerAsyncTest(testText, transformToOutcome(testFun), Resources.testCannotBeNestedInsideAnotherTest, None, None, pos, testTags: _*)
  }

  // SKIP-DOTTY-START
  final def registerAsyncTest(testText: String, testTags: Tag*)(testFun: FixtureParam => Future[compatible.Assertion])(implicit pos: source.Position): Unit = {
    registerAsyncTestImpl(testText, testTags: _*)(testFun, pos)
  }
  // SKIP-DOTTY-END
  //DOTTY-ONLY inline final def registerAsyncTest(testText: String, testTags: Tag*)(testFun: FixtureParam => Future[compatible.Assertion])(implicit pos: source.Position): Unit = {
  //DOTTY-ONLY   ${ source.Position.withPosition[Unit]('{(pos: source.Position) => registerAsyncTestImpl(testText, testTags: _*)(testFun, pos) }) } 
  //DOTTY-ONLY }

  private final def registerIgnoredAsyncTestImpl(testText: String, testTags: Tag*)(testFun: FixtureParam => Future[compatible.Assertion], pos: source.Position): Unit = {
    engine.registerIgnoredAsyncTest(testText, transformToOutcome(testFun), Resources.testCannotBeNestedInsideAnotherTest, None, pos, testTags: _*)
  }

  // SKIP-DOTTY-START
  final def registerIgnoredAsyncTest(testText: String, testTags: Tag*)(testFun: FixtureParam => Future[compatible.Assertion])(implicit pos: source.Position): Unit = {
    registerIgnoredAsyncTestImpl(testText, testTags: _*)(testFun, pos)
  }
  // SKIP-DOTTY-END
  //DOTTY-ONLY inline final def registerIgnoredAsyncTest(testText: String, testTags: Tag*)(testFun: FixtureParam => Future[compatible.Assertion])(implicit pos: source.Position): Unit = {
  //DOTTY-ONLY   ${ source.Position.withPosition[Unit]('{(pos: source.Position) => registerIgnoredAsyncTestImpl(testText, testTags: _*)(testFun, pos) }) } 
  //DOTTY-ONLY }

  /**
   * Register a test with the given spec text, optional tags, and test function value that takes no arguments.
   * An invocation of this method is called an &ldquo;example.&rdquo;
   *
   * This method will register the test for later execution via an invocation of one of the <code>execute</code>
   * methods. The name of the test will be a concatenation of the text of all surrounding describers,
   * from outside in, and the passed spec text, with one space placed between each item. (See the documenation
   * for <code>testNames</code> for an example.) The resulting test name must not have been registered previously on
   * this <code>FixtureAsyncFreeSpec</code> instance.
   *
   * @param specText the specification text, which will be combined with the descText of any surrounding describers
   * to form the test name
   * @param testTags the optional list of tags for this test
   * @param methodName caller's method name
   * @param testFun the test function
   * @throws DuplicateTestNameException if a test with the same name has been registered previously
   * @throws TestRegistrationClosedException if invoked after <code>run</code> has been invoked on this suite
   * @throws NullArgumentException if <code>specText</code> or any passed test tag is <code>null</code>
   */
  private def registerAsyncTestToRun(specText: String, testTags: List[Tag], methodName: String, testFun: FixtureParam => Future[compatible.Assertion], pos: source.Position): Unit = {
    engine.registerAsyncTest(specText, transformToOutcome(testFun), Resources.inCannotAppearInsideAnotherIn, None, None, pos, testTags: _*)
  }

  private def registerPendingTestToRun(specText: String, testTags: List[Tag], methodName: String, testFun: FixtureParam => PendingStatement, pos: source.Position): Unit = {
    engine.registerAsyncTest(specText, AsyncPendingTransformer(testFun), Resources.inCannotAppearInsideAnotherIn, None, None, pos, testTags: _*)
  }

  /**
   * Register a test to ignore, which has the given spec text, optional tags, and test function value that takes no arguments.
   * This method will register the test for later ignoring via an invocation of one of the <code>execute</code>
   * methods. This method exists to make it easy to ignore an existing test by changing the call to <code>it</code>
   * to <code>ignore</code> without deleting or commenting out the actual test code. The test will not be executed, but a
   * report will be sent that indicates the test was ignored. The name of the test will be a concatenation of the text of all surrounding describers,
   * from outside in, and the passed spec text, with one space placed between each item. (See the documenation
   * for <code>testNames</code> for an example.) The resulting test name must not have been registered previously on
   * this <code>FixtureAsyncFreeSpec</code> instance.
   *
   * @param specText the specification text, which will be combined with the descText of any surrounding describers
   * to form the test name
   * @param testTags the optional list of tags for this test
   * @param methodName caller's method name
   * @param testFun the test function
   * @throws DuplicateTestNameException if a test with the same name has been registered previously
   * @throws TestRegistrationClosedException if invoked after <code>run</code> has been invoked on this suite
   * @throws NullArgumentException if <code>specText</code> or any passed test tag is <code>null</code>
   */
  private def registerAsyncTestToIgnore(specText: String, testTags: List[Tag], methodName: String, testFun: FixtureParam => Future[compatible.Assertion], pos: source.Position): Unit = {
    engine.registerIgnoredAsyncTest(specText, transformToOutcome(testFun), Resources.ignoreCannotAppearInsideAnIn, None, pos, testTags: _*)
  }

  private def registerPendingTestToIgnore(specText: String, testTags: List[Tag], methodName: String, testFun: FixtureParam => PendingStatement, pos: source.Position): Unit = {
    engine.registerIgnoredAsyncTest(specText, AsyncPendingTransformer(testFun), Resources.ignoreCannotAppearInsideAnIn, None, pos, testTags: _*)
  }
  /*
 private def registerBranch(description: String, childPrefix: Option[String], fun: () => Unit) {

   // TODO: Fix the resource name and method name
   registerNestedBranch(description, childPrefix, fun(), "describeCannotAppearInsideAnIt", sourceFileName, "describe")
 }  */

  /**
   * Class that supports the registration of tagged tests.
   *
   * <p>
   * Instances of this class are returned by the <code>taggedAs</code> method of
   * class <code>FreeSpecStringWrapper</code>.
   * </p>
   *
   * @param specText the specification text
   * @param tags the list of tags
   *
   * @author Bill Venners
   * @author Chee Seng
   */
  protected final class ResultOfTaggedAsInvocationOnString(specText: String, tags: List[Tag], pos: source.Position) {

    /**
     * Supports tagged test registration.
     *
     * <p>
     * For example, this method supports syntax such as the following:
     * </p>
     *
     * <pre class="stHighlight">
     * "complain on peek" taggedAs(SlowTest) in { fixture => ... }
     *                                       ^
     * </pre>
     *
     * <p>
     * For more information and examples of this method's use, see the <a href="FixtureAsyncFreeSpec.html">main documentation</a> for trait <code>FixtureAsyncFreeSpec</code>.
     * </p>
     *
     * @param testFun the test function
     */
    //DOTTY-ONLY     infix  
    def in(testFun: FixtureParam => Future[compatible.Assertion]): Unit = {
      registerAsyncTestToRun(specText, tags, "in", testFun, pos)
    }

    /**
     * Supports tagged test registration, for tests that don't take a fixture.
     *
     * <p>
     * For example, this method supports syntax such as the following:
     * </p>
     *
     * <pre class="stHighlight">
     * "complain on peek" taggedAs(SlowTest) in { () => ... }
     *                                       ^
     * </pre>
     *
     * <p>
     * For more information and examples of this method's use, see the <a href="FixtureAsyncFreeSpec.html">main documentation</a> for trait <code>FixtureAsyncFreeSpec</code>.
     * </p>
     *
     * @param testFun the test function
     */
    //DOTTY-ONLY     infix  
    def in(testFun: () => Future[compatible.Assertion]): Unit = {
      registerAsyncTestToRun(specText, tags, "in", new NoArgTestWrapper(testFun), pos)
    }

    /**
     * Supports registration of tagged, pending tests.
     *
     * <p>
     * For example, this method supports syntax such as the following:
     * </p>
     *
     * <pre class="stHighlight">
     * "complain on peek" taggedAs(SlowTest) is (pending)
     *                                       ^
     * </pre>
     *
     * <p>
     * For more information and examples of this method's use, see the <a href="FixtureAsyncFreeSpec.html">main documentation</a> for trait <code>FixtureAsyncFreeSpec</code>.
     * </p>
     *
     * @param testFun the test function
     */
    //DOTTY-ONLY     infix  
    def is(testFun: => PendingStatement): Unit = {
      registerPendingTestToRun(specText, tags, "is", unusedFixtureParam => testFun, pos)
    }

    /**
     * Supports registration of tagged, ignored tests.
     *
     * <p>
     * For example, this method supports syntax such as the following:
     * </p>
     *
     * <pre class="stHighlight">
     * "complain on peek" taggedAs(SlowTest) ignore { fixture => ... }
     *                                       ^
     * </pre>
     *
     * <p>
     * For more information and examples of this method's use, see the <a href="FixtureAsyncFreeSpec.html">main documentation</a> for trait <code>FixtureAsyncFreeSpec</code>.
     * </p>
     *
     * @param testFun the test function
     */
    //DOTTY-ONLY     infix  
    def ignore(testFun: FixtureParam => Future[compatible.Assertion]): Unit = {
      registerAsyncTestToIgnore(specText, tags, "ignore", testFun, pos)
    }

    /**
     * Supports registration of tagged, ignored tests that take no fixture parameter.
     *
     * <p>
     * For example, this method supports syntax such as the following:
     * </p>
     *
     * <pre class="stHighlight">
     * "complain on peek" taggedAs(SlowTest) ignore { () => ... }
     *                                       ^
     * </pre>
     *
     * <p>
     * For more information and examples of this method's use, see the <a href="FixtureAsyncFreeSpec.html">main documentation</a> for trait <code>FixtureAsyncFreeSpec</code>.
     * </p>
     *
     * @param testFun the test function
     */
    //DOTTY-ONLY     infix  
    def ignore(testFun: () => Future[compatible.Assertion]): Unit = {
      registerAsyncTestToIgnore(specText, tags, "ignore", new NoArgTestWrapper(testFun), pos)
    }
  }

  /**
   * A class that via an implicit conversion (named <code>convertToFreeSpecStringWrapper</code>) enables
   * methods <code>when</code>, <code>that</code>, <code>in</code>, <code>is</code>, <code>taggedAs</code>
   * and <code>ignore</code> to be invoked on <code>String</code>s.
   *
   * <p>
   * This class provides much of the syntax for <code>FixtureAsyncFreeSpec</code>, however, it does not add
   * the verb methods (<code>should</code>, <code>must</code>, and <code>can</code>) to <code>String</code>.
   * Instead, these are added via the <code>ShouldVerb</code>, <code>MustVerb</code>, and <code>CanVerb</code>
   * traits, which <code>FixtureAsyncFreeSpec</code> mixes in, to avoid a conflict with implicit conversions provided
   * in <code>Matchers</code> and <code>MustMatchers</code>.
   * </p>
   *
   * @param string the string that is wrapped
   *
   * @author Bill Venners
   */
  protected final class FreeSpecStringWrapper(string: String, pos: source.Position) {

    /**
     * Register some text that may surround one or more tests. Thepassed function value may contain surrounding text
     * registrations (defined with dash (<code>-</code>)) and/or tests (defined with <code>in</code>). This trait's
     * implementation of this method will register the text (passed to the contructor of <code>FreeSpecStringWrapper</code>
     * and immediately invoke the passed function.
     */
    def -(fun: => Unit): Unit = {
      try {
        registerNestedBranch(string, None, fun, Resources.dashCannotAppearInsideAnIn, None, pos)
      }
      catch {
        case e: TestFailedException => throw new NotAllowedException(FailureMessages.assertionShouldBePutInsideInClauseNotDashClause, Some(e), e.position.getOrElse(pos))
        case e: TestCanceledException => throw new NotAllowedException(FailureMessages.assertionShouldBePutInsideInClauseNotDashClause, Some(e), e.position.getOrElse(pos))
        case tgce: TestRegistrationClosedException => throw tgce
        case e: DuplicateTestNameException => throw new NotAllowedException(FailureMessages.exceptionWasThrownInDashClause(Prettifier.default, UnquotedString(e.getClass.getName), string, e.getMessage), Some(e), e.position.getOrElse(pos))
        case other: Throwable if (!Suite.anExceptionThatShouldCauseAnAbort(other)) => throw new NotAllowedException(FailureMessages.exceptionWasThrownInDashClause(Prettifier.default, UnquotedString(other.getClass.getName), string, other.getMessage), Some(other), pos)
        case other: Throwable => throw other
      }
    }

    /**
     * Supports test registration.
     *
     * <p>
     * For example, this method supports syntax such as the following:
     * </p>
     *
     * <pre class="stHighlight">
     * "complain on peek" in { fixture => ... }
     *                    ^
     * </pre>
     *
     * <p>
     * For more information and examples of this method's use, see the <a href="FixtureAsyncFreeSpec.html">main documentation</a> for trait <code>FixtureAsyncFreeSpec</code>.
     * </p>
     *
     * @param testFun the test function
     */
    //DOTTY-ONLY     infix  
    def in(testFun: FixtureParam => Future[compatible.Assertion]): Unit = {
      registerAsyncTestToRun(string, List(), "in", testFun, pos)
    }

    /**
     * Supports registration of tests that take no fixture.
     *
     * <p>
     * For example, this method supports syntax such as the following:
     * </p>
     *
     * <pre class="stHighlight">
     * "complain on peek" in { () => ... }
     *                    ^
     * </pre>
     *
     * <p>
     * For more information and examples of this method's use, see the <a href="FixtureAsyncFreeSpec.html">main documentation</a> for trait <code>FixtureAsyncFreeSpec</code>.
     * </p>
     *
     * @param testFun the test function
     */
    //DOTTY-ONLY     infix  
    def in(testFun: () => Future[compatible.Assertion]): Unit = {
      registerAsyncTestToRun(string, List(), "in", new NoArgTestWrapper(testFun), pos)
    }

    /**
     * Supports pending test registration.
     *
     * <p>
     * For example, this method supports syntax such as the following:
     * </p>
     *
     * <pre class="stHighlight">
     * "complain on peek" is (pending)
     *                    ^
     * </pre>
     *
     * <p>
     * For more information and examples of this method's use, see the <a href="FixtureAsyncFreeSpec.html">main documentation</a> for trait <code>FixtureAsyncFreeSpec</code>.
     * </p>
     *
     * @param testFun the test function
     */
    //DOTTY-ONLY     infix  
    def is(testFun: => PendingStatement): Unit = {
      registerPendingTestToRun(string, List(), "is", unusedFixtureParam => testFun, pos)
    }

    /**
     * Supports ignored test registration.
     *
     * <p>
     * For example, this method supports syntax such as the following:
     * </p>
     *
     * <pre class="stHighlight">
     * "complain on peek" ignore { fixture => ... }
     *                    ^
     * </pre>
     *
     * <p>
     * For more information and examples of this method's use, see the <a href="FixtureAsyncFreeSpec.html">main documentation</a> for trait <code>FixtureAsyncFreeSpec</code>.
     * </p>
     *
     * @param testFun the test function
     */
    //DOTTY-ONLY     infix  
    def ignore(testFun: FixtureParam => Future[compatible.Assertion]): Unit = {
      registerAsyncTestToIgnore(string, List(), "ignore", testFun, pos)
    }

    /**
     * Supports registration of ignored tests that take no fixture.
     *
     * <p>
     * For example, this method supports syntax such as the following:
     * </p>
     *
     * <pre class="stHighlight">
     * "complain on peek" ignore { () => ... }
     *                    ^
     * </pre>
     *
     * <p>
     * For more information and examples of this method's use, see the <a href="FixtureAsyncFreeSpec.html">main documentation</a> for trait <code>FixtureAsyncFreeSpec</code>.
     * </p>
     *
     * @param testFun the test function
     */
    //DOTTY-ONLY     infix  
    def ignore(testFun: () => Future[compatible.Assertion]): Unit = {
      registerAsyncTestToIgnore(string, List(), "ignore", new NoArgTestWrapper(testFun), pos)
    }

    /**
     * Supports tagged test registration.
     *
     * <p>
     * For example, this method supports syntax such as the following:
     * </p>
     *
     * <pre class="stHighlight">
     * "complain on peek" taggedAs(SlowTest) in { fixture => ... }
     *                    ^
     * </pre>
     *
     * <p>
     * For more information and examples of this method's use, see the <a href="FixtureAsyncFreeSpec.html">main documentation</a> for trait <code>FixtureAsyncFreeSpec</code>.
     * </p>
     *
     * @param firstTestTag the first mandatory test tag
     * @param otherTestTags the others additional test tags
     */
    //DOTTY-ONLY     infix  
    def taggedAs(firstTestTag: Tag, otherTestTags: Tag*): ResultOfTaggedAsInvocationOnString = {
      val tagList = firstTestTag :: otherTestTags.toList
      new ResultOfTaggedAsInvocationOnString(string, tagList, pos)
    }
  }

  // SKIP-DOTTY-START
  import scala.language.implicitConversions
  // SKIP-DOTTY-END

  /**
   * Implicitly converts <code>String</code>s to <code>FreeSpecStringWrapper</code>, which enables
   * methods <code>when</code>, <code>that</code>, <code>in</code>, <code>is</code>, <code>taggedAs</code>
   * and <code>ignore</code> to be invoked on <code>String</code>s.
   */
  // SKIP-DOTTY-START 
  protected implicit def convertToFreeSpecStringWrapper(s: String)(implicit pos: source.Position): FreeSpecStringWrapper = new FreeSpecStringWrapper(s, pos)
  // SKIP-DOTTY-END
  //DOTTY-ONLY protected def convertToFreeSpecStringWrapper(s: String)(using pos: source.Position): FreeSpecStringWrapper = new FreeSpecStringWrapper(s, pos)

  //DOTTY-ONLY  /**
  //DOTTY-ONLY  * Extension methods to enable methods <code>in</code>, <code>is</code>, <code>taggedAs</code> and <code>ignore</code>,
  //DOTTY-ONLY  * as well as the dash operator (<code>-</code>), to be invoked on <code>String</code>s.
  //DOTTY-ONLY  */
  //DOTTY-ONLY extension (s: String)(using pos: source.Position) {
  //DOTTY-ONLY /**
  //DOTTY-ONLY    * Register some text that may surround one or more tests. Thepassed function value may contain surrounding text
  //DOTTY-ONLY    * registrations (defined with dash (<code>-</code>)) and/or tests (defined with <code>in</code>). This trait's
  //DOTTY-ONLY    * implementation of this method will register the text (passed to the contructor of <code>FreeSpecStringWrapper</code>
  //DOTTY-ONLY    * and immediately invoke the passed function.
  //DOTTY-ONLY    */
  //DOTTY-ONLY   def -(fun: => Unit): Unit = new FreeSpecStringWrapper(s, pos).-(fun)
  //DOTTY-ONLY   /**
  //DOTTY-ONLY    * Supports test registration.
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * <p>
  //DOTTY-ONLY    * For example, this method supports syntax such as the following:
  //DOTTY-ONLY    * </p>
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * <pre class="stHighlight">
  //DOTTY-ONLY    * "complain on peek" in { fixture => ... }
  //DOTTY-ONLY    *                    ^
  //DOTTY-ONLY    * </pre>
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * <p>
  //DOTTY-ONLY    * For more information and examples of this method's use, see the <a href="FixtureAsyncFreeSpec.html">main documentation</a> for trait <code>FixtureAsyncFreeSpec</code>.
  //DOTTY-ONLY    * </p>
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * @param testFun the test function
  //DOTTY-ONLY    */
  //DOTTY-ONLY   def in(testFun: FixtureParam => Future[compatible.Assertion]): Unit = new FreeSpecStringWrapper(s, pos).in(testFun)
  //DOTTY-ONLY   /**
  //DOTTY-ONLY    * Supports registration of tests that take no fixture.
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * <p>
  //DOTTY-ONLY    * For example, this method supports syntax such as the following:
  //DOTTY-ONLY    * </p>
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * <pre class="stHighlight">
  //DOTTY-ONLY    * "complain on peek" in { () => ... }
  //DOTTY-ONLY    *                    ^
  //DOTTY-ONLY    * </pre>
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * <p>
  //DOTTY-ONLY    * For more information and examples of this method's use, see the <a href="FixtureAsyncFreeSpec.html">main documentation</a> for trait <code>FixtureAsyncFreeSpec</code>.
  //DOTTY-ONLY    * </p>
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * @param testFun the test function
  //DOTTY-ONLY    */  
  //DOTTY-ONLY   def in(testFun: () => Future[compatible.Assertion]): Unit = new FreeSpecStringWrapper(s, pos).in(testFun)
  //DOTTY-ONLY   /**
  //DOTTY-ONLY    * Supports pending test registration.
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * <p>
  //DOTTY-ONLY    * For example, this method supports syntax such as the following:
  //DOTTY-ONLY    * </p>
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * <pre class="stHighlight">
  //DOTTY-ONLY    * "complain on peek" is (pending)
  //DOTTY-ONLY    *                    ^
  //DOTTY-ONLY    * </pre>
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * <p>
  //DOTTY-ONLY    * For more information and examples of this method's use, see the <a href="FixtureAsyncFreeSpec.html">main documentation</a> for trait <code>FixtureAsyncFreeSpec</code>.
  //DOTTY-ONLY    * </p>
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * @param testFun the test function
  //DOTTY-ONLY    */
  //DOTTY-ONLY   def is(testFun: => PendingStatement): Unit = new FreeSpecStringWrapper(s, pos).is(testFun)
  //DOTTY-ONLY   /**
  //DOTTY-ONLY    * Supports ignored test registration.
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * <p>
  //DOTTY-ONLY    * For example, this method supports syntax such as the following:
  //DOTTY-ONLY    * </p>
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * <pre class="stHighlight">
  //DOTTY-ONLY    * "complain on peek" ignore { fixture => ... }
  //DOTTY-ONLY    *                    ^
  //DOTTY-ONLY    * </pre>
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * <p>
  //DOTTY-ONLY    * For more information and examples of this method's use, see the <a href="FixtureAsyncFreeSpec.html">main documentation</a> for trait <code>FixtureAsyncFreeSpec</code>.
  //DOTTY-ONLY    * </p>
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * @param testFun the test function
  //DOTTY-ONLY    */
  //DOTTY-ONLY   def ignore(testFun: FixtureParam => Future[compatible.Assertion]): Unit = new FreeSpecStringWrapper(s, pos).ignore(testFun)
  //DOTTY-ONLY   /**
  //DOTTY-ONLY    * Supports registration of ignored tests that take no fixture.
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * <p>
  //DOTTY-ONLY    * For example, this method supports syntax such as the following:
  //DOTTY-ONLY    * </p>
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * <pre class="stHighlight">
  //DOTTY-ONLY    * "complain on peek" ignore { () => ... }
  //DOTTY-ONLY    *                    ^
  //DOTTY-ONLY    * </pre>
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * <p>
  //DOTTY-ONLY    * For more information and examples of this method's use, see the <a href="FixtureAsyncFreeSpec.html">main documentation</a> for trait <code>FixtureAsyncFreeSpec</code>.
  //DOTTY-ONLY    * </p>
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * @param testFun the test function
  //DOTTY-ONLY    */
  //DOTTY-ONLY   def ignore(testFun: () => Future[compatible.Assertion]): Unit = new FreeSpecStringWrapper(s, pos).ignore(testFun)
  //DOTTY-ONLY   /**
  //DOTTY-ONLY    * Supports tagged test registration.
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * <p>
  //DOTTY-ONLY    * For example, this method supports syntax such as the following:
  //DOTTY-ONLY    * </p>
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * <pre class="stHighlight">
  //DOTTY-ONLY    * "complain on peek" taggedAs(SlowTest) in { fixture => ... }
  //DOTTY-ONLY    *                    ^
  //DOTTY-ONLY    * </pre>
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * <p>
  //DOTTY-ONLY    * For more information and examples of this method's use, see the <a href="FixtureAsyncFreeSpec.html">main documentation</a> for trait <code>FixtureAsyncFreeSpec</code>.
  //DOTTY-ONLY    * </p>
  //DOTTY-ONLY    *
  //DOTTY-ONLY    * @param firstTestTag the first mandatory test tag
  //DOTTY-ONLY    * @param otherTestTags the others additional test tags
  //DOTTY-ONLY    */
  //DOTTY-ONLY   def taggedAs(firstTestTag: Tag, otherTestTags: Tag*): ResultOfTaggedAsInvocationOnString = new FreeSpecStringWrapper(s, pos).taggedAs(firstTestTag, otherTestTags*)
  //DOTTY-ONLY }

  /**
   * A <code>Map</code> whose keys are <code>String</code> tag names to which tests in this <code>FixtureAsyncFreeSpec</code> belong, and values
   * the <code>Set</code> of test names that belong to each tag. If this <code>FixtureAsyncFreeSpec</code> contains no tags, this method returns an empty <code>Map</code>.
   *
   * <p>
   * This trait's implementation returns tags that were passed as strings contained in <code>Tag</code> objects passed to
   * methods <code>test</code> and <code>ignore</code>.
   * </p>
   *
   * <p>
   * In addition, this trait's implementation will also auto-tag tests with class level annotations.
   * For example, if you annotate @Ignore at the class level, all test methods in the class will be auto-annotated with @Ignore.
   * </p>
   */
  override def tags: Map[String, Set[String]] = autoTagClassAnnotations(atomic.get.tagsMap, this)

  /**
   * Run a test. This trait's implementation runs the test registered with the name specified by
   * <code>testName</code>. Each test's name is a concatenation of the text of all describers surrounding a test,
   * from outside in, and the test's  spec text, with one space placed between each item. (See the documenation
   * for <code>testNames</code> for an example.)
   *
   * @param testName the name of one test to execute.
   * @param args the <code>Args</code> for this run
   * @return a <code>Status</code> object that indicates when the test started by this method has completed, and whether or not it failed .
   * @throws NullArgumentException if <code>testName</code> or <code><args/code> is <code>null</code>.
   */
  protected override def runTest(testName: String, args: Args): Status = {
    def invokeWithAsyncFixture(theTest: TestLeaf, onCompleteFun: Try[Outcome] => Unit): AsyncOutcome = {
      val theConfigMap = args.configMap
      val testData = testDataFor(testName, theConfigMap)
      FutureAsyncOutcome(
        withFixture(
          new OneArgAsyncTest {
            val name = testData.name

            def apply(fixture: FixtureParam): FutureOutcome =
              theTest.testFun(fixture).toFutureOutcome

            val configMap = testData.configMap
            val scopes = testData.scopes
            val text = testData.text
            val tags = testData.tags
            val pos = testData.pos
          }
        ).underlying,
        onCompleteFun
      )
    }

    runTestImpl(thisSuite, testName, args, true, parallelAsyncTestExecution, invokeWithAsyncFixture)
  }

  /**
   * <p>
   * Run zero to many of this <code>FreeSpec</code>'s tests.
   * </p>
   *
   * <p>
   * This method takes a <code>testName</code> parameter that optionally specifies a test to invoke.
   * If <code>testName</code> is <code>Some</code>, this trait's implementation of this method
   * invokes <code>runTest</code> on this object with passed <code>args</code>.
   * </p>
   *
   * <p>
   * This method takes an <code>args</code> that contains a <code>Set</code> of tag names that should be included (<code>tagsToInclude</code>), and a <code>Set</code>
   * that should be excluded (<code>tagsToExclude</code>), when deciding which of this <code>Suite</code>'s tests to execute.
   * If <code>tagsToInclude</code> is empty, all tests will be executed
   * except those those belonging to tags listed in the <code>tagsToExclude</code> <code>Set</code>. If <code>tagsToInclude</code> is non-empty, only tests
   * belonging to tags mentioned in <code>tagsToInclude</code>, and not mentioned in <code>tagsToExclude</code>
   * will be executed. However, if <code>testName</code> is <code>Some</code>, <code>tagsToInclude</code> and <code>tagsToExclude</code> are essentially ignored.
   * Only if <code>testName</code> is <code>None</code> will <code>tagsToInclude</code> and <code>tagsToExclude</code> be consulted to
   * determine which of the tests named in the <code>testNames</code> <code>Set</code> should be run. For more information on trait tags, see the main documentation for this trait.
   * </p>
   *
   * <p>
   * If <code>testName</code> is <code>None</code>, this trait's implementation of this method
   * invokes <code>testNames</code> on this <code>Suite</code> to get a <code>Set</code> of names of tests to potentially execute.
   * (A <code>testNames</code> value of <code>None</code> essentially acts as a wildcard that means all tests in
   * this <code>Suite</code> that are selected by <code>tagsToInclude</code> and <code>tagsToExclude</code> should be executed.)
   * For each test in the <code>testName</code> <code>Set</code>, in the order
   * they appear in the iterator obtained by invoking the <code>elements</code> method on the <code>Set</code>, this trait's implementation
   * of this method checks whether the test should be run based on the <code>tagsToInclude</code> and <code>tagsToExclude</code> <code>Set</code>s.
   * If so, this implementation invokes <code>runTest</code> via passed in <code>args</code>.
   * </p>
   *
   * @param testName an optional name of one test to execute. If <code>None</code>, all relevant tests should be executed.
   *                 I.e., <code>None</code> acts like a wildcard that means execute all relevant tests in this <code>FixtureAsyncFreeSpec</code>.
   * @param args the <code>Args</code> for this run
   * @return a <code>Status</code> object that indicates when all tests started by this method have completed, and whether or not a failure occurred.
   * @throws NullArgumentException if <code>testName</code> or <code>args</code> is <code>null</code>.
   */
  protected override def runTests(testName: Option[String], args: Args): Status = {
    runTestsImpl(thisSuite, testName, args, true, parallelAsyncTestExecution, runTest)
  }

  /**
   * An immutable <code>Set</code> of test names. If this <code>FixtureAsyncFreeSpec</code> contains no tests, this method returns an
   * empty <code>Set</code>.
   *
   * <p>
   * This trait's implementation of this method will return a set that contains the names of all registered tests. The set's
   * iterator will return those names in the order in which the tests were registered. Each test's name is composed
   * of the concatenation of the text of each surrounding describer, in order from outside in, and the text of the
   * example itself, with all components separated by a space.
   * </p>
   *
   * @return the <code>Set</code> of test names
   */
  override def testNames: Set[String] = {
    InsertionOrderSet(atomic.get.testNamesList)
  }

  override def run(testName: Option[String], args: Args): Status = {
    runImpl(thisSuite, testName, args, parallelAsyncTestExecution, super.run)
  }

  /**
   * Supports shared test registration in <code>FixtureAsyncFreeSpec</code>s.
   *
   * <p>
   * This field enables syntax such as the following:
   * </p>
   *
   * <pre class="stHighlight">
   * behave like nonFullStack(stackWithOneItem)
   * ^
   * </pre>
   *
   * <p>
   * For more information and examples of the use of <cod>behave</code>, see the <a href="AnyFreeSpec.html#SharedTests">Shared tests section</a>
   * in the main documentation for trait <code>AnyFreeSpec</code>.
   * </p>
   */
  protected val behave = new BehaveWord

  override def testDataFor(testName: String, theConfigMap: ConfigMap = ConfigMap.empty): TestData = createTestDataFor(testName, theConfigMap, this)
}
